package com.mentalhealthplatform.global.rbac.controller;

import com.mentalhealthplatform.global.log.manager.ManagerLogAction;
import com.mentalhealthplatform.global.rbac.dto.normal.RoleDTO;
import com.mentalhealthplatform.global.rbac.model.Role;
import com.mentalhealthplatform.global.debounce.Debounce;
import com.mentalhealthplatform.global.rbac.service.entity.RoleService;
import com.mentalhealthplatform.utils.ExportUtils;
import com.mentalhealthplatform.utils.PagedResponse;
import com.mentalhealthplatform.utils.stringUtils.ConvertEmptyToNull;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.List;
import java.util.Map;


@RestController
@RequestMapping("/api/roles")
public class RoleController {

    private static final Logger logger = LoggerFactory.getLogger(RoleController.class);

    @Autowired
    private RoleService roleService;

    @GetMapping
    @Debounce
    @PreAuthorize("hasAuthority('ROLE:READ_ALL')")
    public ResponseEntity<PagedResponse<RoleDTO>> getAllRoles(
            @RequestParam(required = false) @ConvertEmptyToNull String displayName,   // 角色名称
            @RequestParam(defaultValue = "1") int page,                            // 默认页码为1
            @RequestParam(defaultValue = "10") int pageSize,                       // 默认每页大小为10
            @RequestParam(required = false) String sortField,                      // 排序字段
            @RequestParam(required = false) String sortOrder) {                    // 排序顺序

        try {
            // 调用 Service 层获取分页数据
            PagedResponse<RoleDTO> result = roleService.getRoles(displayName, page - 1, pageSize, sortField, sortOrder);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            // 统一的异常处理
            return ResponseEntity.status(500).body(null);
        }
    }

    @GetMapping("/all")
    @Debounce
    @PreAuthorize("hasAuthority('ROLE:READ_ALL')")
    public ResponseEntity<List<RoleDTO>> getAllRolesWithoutPagination() {
        try {
            // 调用 Service 层获取所有角色数据
            List<RoleDTO> allRoles = roleService.getAllRoles();

            return ResponseEntity.ok(allRoles);
        } catch (Exception e) {
            // 统一的异常处理
            return ResponseEntity.status(500).body(null);
        }
    }


    // 创建角色
    @PostMapping
    @ManagerLogAction(module = "角色管理", operationType = "新增")
    @Debounce
    @PreAuthorize("hasAuthority('ROLE:CREATE')")
    public ResponseEntity<?> createRole(@RequestBody RoleDTO roleDTO) {
        try {
            Role newRole = roleService.createRole(roleDTO);
            RoleDTO newRoleDTO = RoleDTO.convertToDTO(newRole);
            return ResponseEntity.status(201).body(newRoleDTO);
        } catch (Exception e) {
            return ResponseEntity.status(500).body("角色创建失败: " + e.getMessage());
        }
    }

    // 删除角色
    @DeleteMapping("/{id}")
    @ManagerLogAction(module = "角色管理", operationType = "删除")
    @Debounce
    @PreAuthorize("hasAuthority('ROLE:DELETE')")
    public ResponseEntity<?> deleteRole(@PathVariable Long id) {
        roleService.deleteRoleById(id);
        return ResponseEntity.noContent().build();
    }

    // 批量删除角色
    @PostMapping("/delete")
    @Debounce
    @PreAuthorize("hasAuthority('ROLE:DELETE_ALL')")
    public ResponseEntity<?> deleteRoles(@RequestBody List<Long> ids) {
        try {
            ids.forEach(roleService::deleteRole);
            return ResponseEntity.noContent().build();
        } catch (Exception e) {
            return ResponseEntity.status(500).body("批量删除失败: " + e.getMessage());
        }
    }


    @PutMapping("/{id}/status")
    @Debounce
    @PreAuthorize("hasAuthority('ROLE:STATUS_UPDATE')")
    public ResponseEntity<?> updateRoleStatus(@PathVariable Long id, @RequestBody Map<String, Boolean> status) {
        try {
            roleService.updateRoleStatus(id, status.get("status"));
            return ResponseEntity.ok("角色状态更新成功");
        } catch (Exception e) {
            return ResponseEntity.status(500).body("角色状态更新失败: " + e.getMessage());
        }
    }


    // 更新角色信息
    @PutMapping("/{roleId}")
    @Debounce
    @PreAuthorize("hasAuthority('ROLE:UPDATE')")
    public ResponseEntity<?> updateRole(
            @PathVariable Long roleId,
            @RequestBody RoleDTO roleDTO) {
        try {
            roleService.updateRole(roleId, roleDTO);
            return ResponseEntity.ok("角色基本信息更新成功");
        } catch (Exception e) {
            return ResponseEntity.status(500).body("角色更新失败: " + e.getMessage());
        }
    }

    // 给角色授予菜单
    @PostMapping("/{roleId}/menus")
    @Debounce
    @PreAuthorize("hasAuthority('ROLE:MENU_ASSIGN')")
    public ResponseEntity<?> assignMenusToRole(@PathVariable Long roleId, @RequestBody List<Long> menuIds) {
        try {
            roleService.assignMenusToRole(roleId, menuIds);
            return ResponseEntity.ok("菜单授予成功");
        } catch (Exception e) {
            return ResponseEntity.status(500).body("菜单授予失败: " + e.getMessage());
        }
    }

    // 给角色授予权限
    @PostMapping("/{roleId}/permissions")
    @Debounce
    @PreAuthorize("hasAuthority('ROLE:PERMISSION_ASSIGN')")
    public ResponseEntity<?> assignPermissionsToRole(@PathVariable Long roleId, @RequestBody List<Long> permissionIds) {
        try {
            roleService.assignPermissionsToRole(roleId, permissionIds);
            return ResponseEntity.ok("权限授予成功");
        } catch (Exception e) {
            return ResponseEntity.status(500).body("权限授予失败: " + e.getMessage());
        }
    }

    // 获取角色的菜单 ID 列表
    @GetMapping("/{roleId}/menus")
    @Debounce
    @PreAuthorize("hasAuthority('ROLE:MENU_ASSIGN')")
    public ResponseEntity<?> getRoleMenus(@PathVariable Long roleId) {
        try {
            List<Long> menuIds = roleService.getMenuIdsByRoleId(roleId);
            return ResponseEntity.ok(menuIds);
        } catch (Exception e) {
            return ResponseEntity.status(500).body("获取菜单失败: " + e.getMessage());
        }
    }

    // 移除角色的菜单
    @DeleteMapping("/{roleId}/menus")
    @Debounce
    @PreAuthorize("hasAuthority('ROLE:MENU_REMOVE')")
    public ResponseEntity<?> removeMenusFromRole(@PathVariable Long roleId, @RequestBody List<Long> menuIds) {
        try {
            roleService.removeMenusFromRole(roleId, menuIds);
            return ResponseEntity.noContent().build();
        } catch (Exception e) {
            return ResponseEntity.status(500).body("移除菜单失败: " + e.getMessage());
        }
    }

    // 获取角色的权限 ID 列表
    @GetMapping("/{roleId}/permissions")
    @Debounce
    @PreAuthorize("hasAuthority('ROLE:PERMISSION_ASSIGN')")
    public ResponseEntity<?> getRolePermissions(@PathVariable Long roleId) {
        try {
            List<Long> permissionIds = roleService.getPermissionIdsByRoleId(roleId);
            return ResponseEntity.ok(permissionIds);
        } catch (Exception e) {
            return ResponseEntity.status(500).body("获取权限失败: " + e.getMessage());
        }
    }

    // 移除角色的权限
    @DeleteMapping("/{roleId}/permissions")
    @Debounce
    @PreAuthorize("hasAuthority('ROLE:PERMISSION_REMOVE')")
    public ResponseEntity<?> removePermissionsFromRole(@PathVariable Long roleId, @RequestBody List<Long> permissionIds) {
        try {
            roleService.removePermissionsFromRole(roleId, permissionIds);
            return ResponseEntity.noContent().build();
        } catch (Exception e) {
            return ResponseEntity.status(500).body("移除权限失败: " + e.getMessage());
        }
    }



    // 导出指定角色信息
    @GetMapping("/export")
    public void exportRoles(HttpServletResponse response,
                            @RequestParam(required = false) List<Long> roleIds) throws IOException {
        // 获取角色数据
        List<RoleDTO> rolesToExport = (roleIds != null && !roleIds.isEmpty())
                ? roleService.getRolesByIds(roleIds)
                : roleService.getAllRoles();

        // 调用工具类导出
        ExportUtils.exportToExcel(response, rolesToExport, "角色信息", RoleDTO.class, "角色信息");
    }

    @GetMapping("/export/all")
    public void exportAllRoles(HttpServletResponse response) throws IOException {
        // 获取所有角色信息
        List<RoleDTO> rolesToExport = roleService.getAllRoles();

        // 使用工具类导出数据
        ExportUtils.exportToExcel(response, rolesToExport, "所有角色信息", RoleDTO.class, "角色信息");
    }



}
